package com.yupi.springbootinit.utils.svn;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.*;

import javax.annotation.PostConstruct;
import java.io.File;

/**
 * @Author 史祥连
 * @Date 2023/12/7 13:29
 * @Version 1.0
 */
@Component
@Slf4j
@Scope("prototype")
public class SVNUtil {

    @Value("${weaver.svn.userName:shxl2021}")
    private String userName;
    @Value("${weaver.svn.passWord:ff8d7o0rmc2j7}")
    private String passWord;
    @Value("${weaver.svn.localBasePath:C:\\Datas\\E9\\客户分支\\}")
    private String localBasePath;

    private SVNClientManager clientManager;
    private ISVNAuthenticationManager authManager;

    @PostConstruct
    private void load() {
        ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(userName, passWord);
        clientManager = SVNClientManager.newInstance((ISVNOptions) null, authManager);
    }

    public void add(String projectPath) throws SVNException {
        File repositoryFile = new File(projectPath);
        SVNStatusClient statusClient = clientManager.getStatusClient();
        statusClient.doStatus(repositoryFile, SVNRevision.BASE, SVNDepth.INFINITY, false, false, true, false,
                new ISVNStatusHandler() {
                    @Override
                    public void handleStatus(SVNStatus status) throws SVNException {
                        // 获取未受版本控制的文件
                        if (status.getContentsStatus() == SVNStatusType.STATUS_NONE) {
                            // 添加未被版本控制的文件到SVN
                            clientManager.getWCClient().doAdd(status.getFile(), false, false, false, SVNDepth.INFINITY, false, false, true);
                            log.info("Added: " + status.getFile());
                        }
                    }
                }, null);
    }

    public SVNCommitInfo commit(String projectPath, String commitMsg) {
        File repositoryFile = new File(projectPath);

        try {
            // 创建SVNCommitClient实例
            SVNCommitClient commitClient = clientManager.getCommitClient();

            // 提交文件到SVN服务器
            SVNCommitInfo svnCommitInfo = commitClient.doCommit(new File[]{repositoryFile}, true, commitMsg, null, null, false, false, SVNDepth.INFINITY);
            return svnCommitInfo;
        } catch (SVNException e) {
            log.error("提交失败：",e);
            throw new RuntimeException(e);
        }
    }

    public String checkout(String svnLocation,boolean isClearLocal) {
        String[] split = svnLocation.split("/");
        return checkout2(svnLocation, split[split.length - 1],isClearLocal);
    }

    /**
     * 拉去客户svn仓库到本地
     * @param svnUrl 客户远端仓库地址
     * @param projectName 本地仓库名
     * @param isClearLocal 是否需要清理本地原有仓库数据
     * @return
     */
    public String checkout2(String svnUrl, String projectName,boolean isClearLocal) {
        String separator = File.separator;
        if (!localBasePath.endsWith(separator)) {
            localBasePath += separator;
        }
        String projectLocation = localBasePath + projectName;
        //先清理本地缓存
        File file = new File(projectLocation);
        if (file.exists() && isClearLocal) {
            deleteFolder(file);
            log.info("本地缓存已清理");
        }
        // 本地SVN仓库路径（目标路径）
        File localRepositoryDir = new File(projectLocation);
        try {
            SVNURL svnRepositoryURL = SVNURL.parseURIDecoded(svnUrl);

            // 创建SVNClientManager实例

            // 创建SVNUpdateClient实例
            SVNUpdateClient updateClient = clientManager.getUpdateClient();

            // 拉取远程SVN仓库到本地
            updateClient.doCheckout(svnRepositoryURL, localRepositoryDir, SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, false);

            log.info("Repository checked out to: " + localRepositoryDir.getAbsolutePath());
        } catch (SVNException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return projectLocation;
    }
    // 递归删除文件夹及其内容
    public static void deleteFolder(File folder) {
        if (folder.isDirectory()) {
            // 获取文件夹下所有文件和子文件夹
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 递归调用删除文件或文件夹
                    deleteFolder(file);
                }
            }
        }

        // 删除空文件夹或文件
        folder.delete();
    }
    public long getLastCommitVersionId(String svnLocation) {
        SVNRepository repository = null;
        long latestRevision = 0;
        try {
            repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(svnLocation));
            ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager();
            repository.setAuthenticationManager(authManager);
            // 获取最新的版本号
            latestRevision = repository.getLatestRevision();
        } catch (SVNException e) {
            throw new RuntimeException(e);
        } finally {
            if (repository != null) {
                repository.closeSession();
            }
        }

        return latestRevision;
    }

    public SVNUtil reset(String userName, String passWord) {
        this.userName = userName;
        this.passWord = passWord;
        load();
        return this;
    }
}
